using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System;
using System.Globalization;

namespace EvoBoost.Core
{
	[Serializable]
	public class SplitRule<T>
	{
		private readonly ReadOnlyCollection<double> parametersReadOnly;

		private readonly List<double> parameters;

		internal SplitRule(SplitBase<T> split, IEnumerable<double> parameters, double threshold, SplitRuleSign sign)
		{
			Debug.Assert(split != null && parameters != null);
			
			this.Split = split;
			this.Threshold = threshold;
			this.Sign = sign;
			this.parameters = new List<double>(parameters);
			this.parametersReadOnly = new ReadOnlyCollection<double>(this.parameters);
		}

		public ReadOnlyCollection<double> Parameters
		{
			get { return this.parametersReadOnly; }
		}

		public SplitBase<T> Split { get; private set; }

		public double Threshold { get; private set; }

		public SplitRuleSign Sign { get; private set; }

		public bool CoversObject(T properties)
		{
			double value = this.Split.Calculate(properties, this.parameters);
			return
				(this.Sign == SplitRuleSign.LessOrEqual && value <= this.Threshold) ||
				(this.Sign == SplitRuleSign.Greater && value > this.Threshold);
		}

		public override string ToString()
		{
			string parametersString = "[";
			foreach (double parameter in parameters)
				parametersString += parameter + " ";
			if (parametersString.Length > 1)
				parametersString = parametersString.Substring(0, parametersString.Length - 1);	// Remove last space
			parametersString += "]";

			return String.Format(CultureInfo.CurrentCulture, "G={0} T={1} P={2}", this.Sign, this.Threshold, parametersString);
		}
	}
}